/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package foremost;
import forensicsGUI.*;
import forensicsGUI.api.forensicsInstance;
import java.util.Vector;
import javax.swing.*;
import java.awt.*;
import java.io.*;

/**
 * Instance of foremost. 
 * @author marc
 */
public class foremostInstance extends forensicsInstance
{

    private boolean quickMode;
    private boolean partialHeaders;
    private boolean auditOnly;


    // advanced settings
    private int memSize = 1024;
    private int taskCount = 0; // if set to 0, then we don't worry about it
    
    

    private statusFrame associatedFrame = null;
    private boolean parallel=true;

    private JTable reference = null;
    private JTable runningReference = null;
    
    
    public void setBackReference(JTable reference){ this.reference = reference; }
    public void setRunningReference(JTable runningReference){this.runningReference = runningReference; }
    public void setQuickMode( boolean quickMode)
    {
        this.quickMode = quickMode;
    }
    
    public void setPartialHeaders( boolean partialHeaders)
    {
        this.partialHeaders = partialHeaders;
    }
    
    public void setAuditOnly( boolean auditOnly)
    {
        this.auditOnly = auditOnly;
    }
    

    public void setMaxMem(String memSize)
    { 
        try
        {
            this.memSize = new Integer( memSize ).intValue();
        }
        catch(Exception e)
        {
            this.memSize =1024;
        }
        
    }
    public void setMaxThreads(String maxThreads)
    {
     try
        {
            taskCount = new Integer( maxThreads ).intValue();
        }
        catch(Exception e)
        {
            this.taskCount =1024;
        }
    }

    
    public foremostInstance(boolean parallel)
    {
           associatedFrame = new statusFrame(parallel);
          this.parallel = parallel;
          
    }

    public void showFrame()
    {
        associatedFrame.getPanel().removeAll();
        associatedFrame.getPanel().setLayout( new BorderLayout() );
        associatedFrame.getPanel().add(outputLogger.getArea(),BorderLayout.NORTH);
        outputLogger.getArea().setSize( associatedFrame.getPanel().getSize() );
        outputLogger.getArea().updateUI();
        associatedFrame.getPanel().updateUI();
           
        associatedFrame.setVisible(true);
    }
    
    public static boolean validatePFAPI(String loc, String exe)
    {
        try
        {
            if (loc.lastIndexOf("/") == loc.length()-1)
            {
                System.out.println("loc is " + loc);
                loc = loc.substring(0,loc.length()-1);
            }
            String execute = loc + "/" + exe + " -X";    
            Process process = Runtime.getRuntime().exec(execute, null);

            String cmdError = "";
            InputStream stderr = process.getErrorStream();
            InputStreamReader isr = new InputStreamReader(stderr);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ( (line = br.readLine()) != null)
                cmdError+=line;

            
            
            if (cmdError.length() < 12)
                return false;
            if (cmdError.substring(0,12).equals("<PFM>1</PFM>"))
                return true;
            else
                return false;
            
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
    }
    public void saveInvestigationFile()
    {
         try {
                String loc = getOutputDir() + "/investigation.txt";
                File file = new File(loc);

                // Create file if it does not exist
                boolean success = file.createNewFile();
                if (success) {
                    FileWriter fstream = new FileWriter(file);
                    BufferedWriter out = new BufferedWriter(fstream);
                    out.write("Investigator: " + getInvestigatorName() + "\n");
                    out.write("Case Number: " + getCaseNumber() + "\n");
                    out.write("Case Details: " + getCaseDetails() + "\n");
                    out.close();
                } 
            } catch (IOException e) {
            }

    }
    public void run()
    {
        if (hasExecuted() == true)
                return;
        SysCommandExecutor cmdExecutor = new SysCommandExecutor();
        cmdExecutor.setOutputLogDevice(getOutputLogger());
        cmdExecutor.setErrorLogDevice(getErrorLogger());
        String flags = "";
        if (parallel == true)
            flags = "-G -M " + new Integer( memSize ).toString();
        if (quickMode == true)
            flags += " -q ";
        if (partialHeaders == true)
            flags += " -a ";
        if (auditOnly == true)
            flags += " -w ";
        

        if (executableLocation.lastIndexOf("/") == executableLocation.length()-1)
            {
                executableLocation = executableLocation.substring(0,executableLocation.length()-1);
            }
        
        String execute = executableLocation + "/" + executable + " -c " + executableLocation + "/foremost.conf " + flags + "  -o " + outputDir + " -i ";
        if (imageLocations == null)
        {
            GuiNotification.displayNotification("Have not chosen Images","Imaging Error",GuiNotification.ERROR);
            return;
        }
        for (int i=0; i < imageLocations.size(); i++)
        {
            execute +=  imageLocations.get(i) + " ";
        }
        
        try
        {
            associatedFrame.startUpdateTimer(errorLogger);
            int exitStatus = cmdExecutor.runCommand(execute);
            associatedFrame.stopUpdateTimer();
            AuditedInstances newInstance = new AuditedInstances(outputDir,caseNumber);

            
            
            if (currentState != null)
            {
                currentState.addExecutedInstance(newInstance);
            }
            if (runningReference!= null)
                ((ExecutionTableModel)runningReference.getModel()).deleteRow( this );
            if (reference != null)
                reference.getModel().setValueAt(newInstance,1,1);
            saveInvestigationFile();
            associatedFrame.setFinished();
            associatedFrame.loadAuditInformation(newInstance);
            finished = true;
            GuiNotification.displayNotification("Case Number " + caseNumber + " is complete","Analysis Complete",GuiNotification.INFORMATION);
            
         }
         catch ( Exception e)
         {
             e.printStackTrace();
         }
         
    }

}


